<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
            "http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD>



<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<META name="GENERATOR" content="hevea 1.08">
<LINK rel="stylesheet" type="text/css" href="tutorial.css">
<TITLE>
Storing Information Across Backtracking
</TITLE>
</HEAD>
<BODY >
<A HREF="tutorial026.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="tutorial023.html"><IMG SRC ="contents_motif.gif" ALT="Up"></A>
<A HREF="tutorial028.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<HR>

<H2 CLASS="section"><A NAME="htoc55">4.4</A>&nbsp;&nbsp;Storing Information Across Backtracking</H2><UL>
<LI><A HREF="tutorial027.html#toc30">Bags</A>
<LI><A HREF="tutorial027.html#toc31">Shelves</A>
</UL>

In pure logic programming, the complete state of a computation is
reset to an earlier state on backtracking.
The all-solutions predicates introduced in section <A HREF="tutorial019.html#all-solutions">3.7.4</A>
provide a way to collect solutions across backtracking.<BR>
<BR>
The following section presents ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>'s lower-level primitives for storing
information across failures: bags and shelves.
Both bags and shelves are referred to by handle, not by name,
so they make it easy to write robust, reentrant code.
Bags and shelves disappear when the system backtracks over their
creation, when the handle gets garbage collected, or when they are
destroyed explicitly.<BR>
<BR>
<A NAME="toc30"></A>
<H3 CLASS="subsection"><A NAME="htoc56">4.4.1</A>&nbsp;&nbsp;Bags</H3>
A bag is an anonymous object which can be used to store information
across failures. A typical application is the collection of
alternative solutions.<BR>
<BR>
A bag is an unordered collection, referred to by a handle.
A bag is created using bag_create/1, terms can be added to a bag using
bag_enter/2, and the whole contents of the bag can be retrieved
using bag_retrieve/2 or bag_dissolve/2.
A simple version of the findall/3 predicate from section <A HREF="tutorial019.html#all-solutions">3.7.4</A>
can be implemented like:

	<TABLE CELLPADDING=10>
<TR><TD BGCOLOR="#CCCCFF">
	<BLOCKQUOTE CLASS="quote"><PRE>
simple_findall(Goal, Solutions) :-
        bag_create(Bag),
        (
            call(Goal),
            bag_enter(Bag, Goal),
            fail
        ;
            bag_dissolve(Bag, Solutions)
        ).
</PRE></BLOCKQUOTE></TD>
</TR></TABLE><BR>
<A NAME="toc31"></A>
<H3 CLASS="subsection"><A NAME="htoc57">4.4.2</A>&nbsp;&nbsp;Shelves</H3>
A shelf is an anonymous object which can be used to store information
across failures. A typical application is counting of solutions,
keeping track of the best solution, 
aggregating information across multiple solutions etc. <BR>
<BR>
A shelf is an object with multiple slots whose contents survive
backtracking. The content of each slot can be set and retrieved
individually, or the whole shelf can be retrieved 
as a term. Shelves are referred to by a handle.<BR>
<BR>
A shelf is initialized using shelf_create / 2 or shelf_create /
3. Data is stored in the slots (or the shelf as a whole) with
shelf_set / 3 and retrieved with shelf_get / 3. <BR>
<BR>
For example, here is a meta-predicate to count the number of solutions
to a goal: 

	<TABLE CELLPADDING=10>
<TR><TD BGCOLOR="#CCCCFF">
	<BLOCKQUOTE CLASS="quote"><PRE>
count_solutions(Goal, Total) :-
    shelf_create(count(0), Shelf),
    (
        call(Goal),
        shelf_get(Shelf, 1, Old),
        New is Old + 1,
        shelf_set(Shelf, 1, New),
        fail
    ;
        shelf_get(Shelf, 1, Total)
    ),
    shelf_abolish(Shelf).
</PRE></BLOCKQUOTE></TD>
</TR></TABLE><BR>
<HR>
<A HREF="tutorial026.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="tutorial023.html"><IMG SRC ="contents_motif.gif" ALT="Up"></A>
<A HREF="tutorial028.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>
